package org.hepeng.chaincode.contract;

import com.alibaba.fastjson.JSON;
import lombok.extern.java.Log;
import org.apache.commons.lang3.StringUtils;
import org.hepeng.chaincode.contract.api.Result;
import org.hepeng.chaincode.contract.api.UserContract;
import org.hepeng.chaincode.contract.api.UserInfo;
import org.hyperledger.fabric.contract.Context;
import org.hyperledger.fabric.contract.ContractInterface;
import org.hyperledger.fabric.contract.annotation.Contact;
import org.hyperledger.fabric.contract.annotation.Contract;
import org.hyperledger.fabric.contract.annotation.Info;
import org.hyperledger.fabric.contract.annotation.License;
import org.hyperledger.fabric.contract.annotation.Transaction;
import org.hyperledger.fabric.shim.ChaincodeException;
import org.hyperledger.fabric.shim.ChaincodeStub;

import java.util.logging.Level;

/**
 * @author he peng
 * @date 2022/3/25
 */

@Contract(
        name = "UserContract",
        transactionSerializer = "org.hepeng.fabric.contract.execution.serializer.ValidationJSONTransactionSerializer" ,
        info = @Info(
                title = "User contract",
                description = "user contract",
                version = "0.0.1-SNAPSHOT",
                license = @License(
                        name = "Apache 2.0 License",
                        url = "http://www.apache.org/licenses/LICENSE-2.0.html"),
                contact = @Contact(
                        email = "f.carr@example.com",
                        name = "User contract",
                        url = "https://hyperledger.example.com")))
@Log
public class UserContractImpl implements UserContract , ContractInterface {

    @Transaction
    @Override
    public Result<UserInfo> regUser(Context ctx, UserInfo userInfo) {
        ChaincodeStub stub = ctx.getStub();
        String user = stub.getStringState(userInfo.getKey());

        if (StringUtils.isNotBlank(user)) {
            String errorMessage = String.format("User %s already exists", userInfo.getKey());
            log.log(Level.ALL , errorMessage);
            return new Result<UserInfo>().setMsg(errorMessage).setPayload(null);
        }

        String json = JSON.toJSONString(userInfo);
        stub.putStringState(userInfo.getKey() , json);

        // publish event
        stub.setEvent("regUserEvent" , org.apache.commons.codec.binary.StringUtils.getBytesUtf8(json));


        return new Result<UserInfo>().setMsg("ok").setPayload(userInfo);
    }

    @Transaction
    @Override
    public Result<UserInfo> getUser(Context ctx, String key) {

        String state = ctx.getStub().getStringState(key);

        if (StringUtils.isBlank(state)) {
            String errorMessage = String.format("User %s does not exist", key);
            log.log(Level.ALL , errorMessage);
            return new Result<UserInfo>().setMsg(errorMessage).setPayload(null);
        }


        return new Result<UserInfo>().setMsg("ok").setPayload(JSON.parseObject(state , UserInfo.class));
    }
}
